package com.starsoft.quant.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.starsoft.frame.base.bean.BaseAcount;
import com.starsoft.frame.base.dao.AcountDao;
import com.starsoft.quant.bean.QuantAcount;
import com.starsoft.quant.bean.QuantModelParam;
import com.starsoft.quant.bean.QuantModelParamData;
import com.starsoft.quant.dao.ModelParamDao;
import com.starsoft.quant.dao.QuantAcountDao;

@Service
public class ModelParamsService {

	@Autowired
	ModelParamDao modelParamDao;
	
	@Autowired
	AcountDao acountDao;
	
	@Autowired
	QuantAcountDao quantAcountDao;

	public List<QuantModelParam> getModelParams(String modelCode) {
		List<QuantModelParam> params = modelParamDao.getModelParam(modelCode);
		return params;
	}
	
	public void saveModelParam(QuantModelParam modelParam){
		modelParamDao.saveOrUpdate(modelParam);
	}
	
	public void deleteModelParam(QuantModelParam modelParam){
		modelParamDao.delete(modelParam);
	}
	
	public List<QuantModelParam> getAcountModelParams(QuantAcount quantAcount) {
		List<QuantModelParam> params = modelParamDao.getModelParam(quantAcount.getModelCode());
		List<QuantModelParamData> paramDatas = modelParamDao.getModelParamData(quantAcount.getAcountId());

		Map<Integer, QuantModelParam> paramsMap = new HashMap<>();
		for (QuantModelParam modelParam : params) {
			paramsMap.put(modelParam.getId(), modelParam);
			modelParam.setValue(modelParam.getDefaultValue());
		}
		for (QuantModelParamData paramData : paramDatas) {
			QuantModelParam modelParam = paramsMap.get(paramData.getParamId());
			if (modelParam == null || !modelParam.getConfigurable()) {
				modelParamDao.deletePamamData(paramData);
			} else {
				modelParam.setValue(paramData.getValue());
			}
		}
		return params;
	}
	
	public Map<String, Object> getAcountModelParamsMap(QuantAcount quantAcount) {
		Map<String, Object> result = new HashMap<String, Object>();
		List<QuantModelParam> params = getAcountModelParams(quantAcount);
		for (QuantModelParam modelParam : params) {
			result.put(modelParam.getParamCode(), modelParam.getValue());
		}
		return result;
	}

	public List<Map<String, Object>> getAcountModelParamsMap(List<BaseAcount> acounts){
		List<Map<String, Object>> result = new ArrayList<Map<String,Object>>();	
		for(BaseAcount acount : acounts){
			QuantAcount quantAcount = quantAcountDao.get(acount.getAcountId());		
			Map<String, Object> paramMap = getAcountModelParamsMap(quantAcount);
			paramMap.put("acountId", acount.getAcountId());
			paramMap.put("acountName", acount.getAcountName());
			result.add(paramMap);
		}
		return result;
	}
	
	public void saveAcountModelParam(QuantAcount acount, Map<String, Object> paramValues) {
		List<QuantModelParam> params = modelParamDao.getModelParam(acount.getModelCode());
		Map<String, QuantModelParam> paramsMap = new HashMap<>();
		for (QuantModelParam modelParam : params) {
			if (modelParam.getConfigurable()) {
				paramsMap.put(modelParam.getParamCode(), modelParam);
			}
		}
		for (Map.Entry<String, Object> entry : paramValues.entrySet()) {
			QuantModelParam modelParam = paramsMap.get(entry.getKey());
			if (modelParam != null) {
				QuantModelParamData paramData = new QuantModelParamData();
				paramData.setParamId(modelParam.getId());
				paramData.setAcountId(acount.getAcountId());
				paramData.setValue(String.valueOf(entry.getValue()));
				modelParamDao.saveParamData(paramData);
			}
		}
	}

	public void detele(QuantAcount quantAcount) {
		List<QuantModelParamData> paramDatas = modelParamDao.getModelParamData(quantAcount.getAcountId());
		for (QuantModelParamData paramData : paramDatas) {
			modelParamDao.deletePamamData(paramData);
		}
	}
	
	public void copy(Integer fromAcount, Integer toAcount){
		List<QuantModelParamData> paramDatas = modelParamDao.getModelParamData(fromAcount);
		for(QuantModelParamData paramData : paramDatas){
			modelParamDao.evict(paramData);
			paramData.setParamId(null);
			paramData.setAcountId(toAcount);
			modelParamDao.saveParamData(paramData);
		}
	}
	

}
